In a recent MVC project I wanted to create a set of widgets to be reused across different pages. I wanted them to be created as a partial view, and be self contained with links to associated JavaScript files. The JavaScipt should be contained in the script section in the partial view, so it is rendered at the bottom of the page. The problem is that MVC does not support the script section in a partial view, for example you can do the following in standard view but not a partial view:
@section scripts {
//Your script here
}
I found a solution for ASP MVC on John Burnham' blog, but it needed some tweaking to work in ASP.Net Core.
First up is to create a couple of HTML helper functions. In summary the first one will add the scripts to the HttpContext.Items, and the second one will render the scripts from the HtppContext.Items:
public static class HtmlHelperExtensions
{
///<summary>
/// Adds a partial view script to the Http context to be rendered in the parent view
/// </summary>
public static IHtmlHelper Script(this IHtmlHelper htmlHelper, Func<object, HelperResult> template)
{
htmlHelper.ViewContext.HttpContext.Items["_script_" + Guid.NewGuid()] = template;
return null;
}
///<summary>
/// Renders any scripts used within the partial views
/// </summary>
///
public static IHtmlHelper RenderPartialViewScripts(this IHtmlHelper htmlHelper)
{
foreach (object key in htmlHelper.ViewContext.HttpContext.Items.Keys)
{
if (key.ToString().StartsWith("_script_"))
{
var template = htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>;
if (template != null)
{
htmlHelper.ViewContext.Writer.Write(template(null));
}
}
}
return null;
}
}
In your partial view add the scripts by wrapping them in the following section:
@Html.Script(
//Your script here
)
And then in you layout view, you render the script with the following:
@Html.RenderPartialViewScripts()